package io.jft.doll.ui.doll

import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.alibaba.android.vlayout.LayoutHelper
import com.alibaba.android.vlayout.layout.GridLayoutHelper
import com.alibaba.android.vlayout.layout.LinearLayoutHelper
import com.g.base.api.ErrorCode
import com.g.base.extend.dp
import com.g.base.extend.observeEx
import com.g.base.extend.resultNotNull
import com.g.base.extend.toast
import com.g.base.room.entity.UserEntity
import com.g.base.room.repository.ListStatus
import com.g.base.room.repository.Status
import com.g.base.router.RouteExtras
import com.g.base.ui.BaseActivity
import com.g.base.ui.recyclerView.item.BaseItem
import com.g.base.ui.recyclerView.setupRecyclerView
import io.jft.doll.R
import io.jft.doll.databinding.ViewSwipeRecyclerBinding
import io.jft.doll.model.viewModel.DollViewModel
import io.jft.doll.room.entity.remote.OwnDollListItemREntity
import io.jft.doll.router.RouterPage
import io.jft.doll.ui.doll.bind.DollDisplayBind
import io.jft.doll.ui.doll.bind.DollUserHeaderBind
import io.jft.doll.ui.dollDetail.DollStatusChangeEvent
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * Created by G on 2017/12/5 0005.
 */
@Route(path = RouterPage.DollActivity, extras = RouteExtras.NeedOauth)
class DollActivity : BaseActivity<ViewSwipeRecyclerBinding>() {
    override var hasToolbar: Boolean = true

    private val dollViewModel by lazy { ViewModelProviders.of(this).get(DollViewModel::class.java) }
    private var listStatus = ListStatus.Content
    private val adapter by lazy { setupRecyclerView(contentView.recyclerView) }

    private val data = ArrayList<OwnDollListItemREntity>()
    private var catchCount = "0"

    @JvmField
    @Autowired()
    var userName: String? = ""

    @JvmField
    @Autowired()
    var thumbnail: String? = ""

    @JvmField
    @Autowired()
    var userId: String? = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ARouter.getInstance().inject(this)

        userName = userName ?: ""
        thumbnail = thumbnail ?: ""
        userId = userId ?: ""

        setContentView(R.layout.view_swipe_recycler)
        initView()
        obsData()
        onReload()
    }

    override fun onReload() {
        dollViewModel.operateDollList(0, userId!!)
    }

    override fun onTokenChange(data: UserEntity?) {
        if (userId!!.isEmpty()) {
            if (data == null)
                showNeedOauth()
            else
                onReload()
        }
    }

    private fun initView() {
        if (userId!!.isNotEmpty())
            toolbar.title = "ta的娃娃"
        else {
            toolbar.title = "我的娃娃"
            toolbar.inflateMenu(R.menu.game_history)
            toolbar.setOnMenuItemClickListener {
                ARouter.getInstance().build(RouterPage.GameHistoryActivity).navigation(this)
                return@setOnMenuItemClickListener true
            }
        }
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_toolbar_24dp)
        toolbar.setNavigationOnClickListener { finishAfterTransition() }

        //下拉刷新
        contentView.swipeLayout.setOnRefreshListener {
            if (listStatus == ListStatus.Content) {
                dollViewModel.operateDollList(0, userId!!)
                listStatus = ListStatus.Refreshing
            } else {
                contentView.swipeLayout.isRefreshing = false
                toast("当前正在刷新数据 请稍后再试...")
            }
        }

        adapter.setOnLoadingListener {
            if (listStatus == ListStatus.Content) {
                dollViewModel.operateDollList(data.size, userId!!)
                listStatus = ListStatus.LoadMore
            } else {
                adapter.setLoadingFailed()
            }
        }
    }


    private fun obsData() {
        dollViewModel.obsDollList()
                .resultNotNull()
                .observeEx(this) {
                    when (it.status) {
                        Status.Loading -> {
                            if (listStatus == ListStatus.Content)
                                showLoading()
                        }
                        Status.Content -> {
                            catchCount = it.data!!.user.amount

                            if (it.data!!.list.size < dollViewModel.dollLimit)
                                adapter.setLoadingNoMore()
                            else
                                adapter.setLoadingSucceed()

                            if (listStatus != ListStatus.LoadMore) {
                                data.clear()
                                contentView.swipeLayout.isRefreshing = false
                            }

                            data.addAll(it.data!!.list)

                            if (listStatus == ListStatus.Content && it.data!!.list.isEmpty()) {
                                applyData(false)
                                showEmpty("暂时还没有抓到娃娃哦~ ")
                            } else {
                                applyData(true)
                                showContentView()
                            }

                            listStatus = ListStatus.Content
                        }
                        Status.Error -> {
                            when (listStatus) {
                                ListStatus.LoadMore -> {
                                    if (it.error?.code == ErrorCode.EMPTY) {
                                        adapter.setLoadingNoMore()
                                    } else {
                                        adapter.setLoadingFailed()
                                    }
                                }
                                ListStatus.Refreshing -> contentView.swipeLayout.isRefreshing = false
                                else -> {
                                    if (it.error?.code == ErrorCode.EMPTY) {
                                        applyData(false)
                                        showEmpty("暂时还没有抓到娃娃哦~ ")
                                    } else {
                                        showError(it.error?.message)
                                    }
                                }
                            }
                            listStatus = ListStatus.Content
                        }
                    }
                }
    }

    private fun applyData(needLoadMore: Boolean) {
        //上拉加载
        if (!needLoadMore)
            adapter.removeOnLoadingListener()

        adapter.diffItems.add(DollUserHeaderBind(userName!!, thumbnail!!, "一共抓中了 $catchCount 次"))
        adapter.diffItems.addAll(data.map {
            DollDisplayBind(it, userId!!.isEmpty()).apply {
                setOnClickListener { _ -> ARouter.getInstance().build(RouterPage.DollDetailActivity).withString("id", it.id).navigation(this@DollActivity) }
            }
        })

        val dp8 = 8.dp()
        adapter.layoutHelpers = arrayListOf(
                LinearLayoutHelper(0, 1) as LayoutHelper,
                (GridLayoutHelper(2, data.size, dp8, dp8).apply { setAutoExpand(false); setPadding(dp8, dp8, dp8, dp8) }) as LayoutHelper
        )

        adapter.calcDiffAndDispatchUpdate(
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    when {
                        baseItem is DollUserHeaderBind && baseItem1 is DollUserHeaderBind -> baseItem.count == baseItem1.count
                        baseItem is DollDisplayBind && baseItem1 is DollDisplayBind -> baseItem.item.id == baseItem1.item.id
                        else -> false
                    }
                },
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    when {
                        baseItem is DollUserHeaderBind && baseItem1 is DollUserHeaderBind -> baseItem.count == baseItem1.count
                        baseItem is DollDisplayBind && baseItem1 is DollDisplayBind -> baseItem.item.id == baseItem1.item.id && baseItem.item.status == baseItem1.item.status
                        else -> false
                    }
                })
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onDollStatusChangeEvent(ev: DollStatusChangeEvent) {
        val index = data.indexOfFirst { ev.id == it.id } + 1
        val dollDisplayBind = adapter.renderItems.getOrNull(index) as? DollDisplayBind
        if (dollDisplayBind?.item?.status != ev.status) {
            dollDisplayBind?.item?.status = ev.status
            adapter.notifyItemChanged(index)
        }
    }
}